package baiqitun.stupro.common.service.support;

import baiqitun.stupro.common.constant.SysConstant;
import baiqitun.stupro.common.exception.enums.support.StuproExceptionEnum;
import baiqitun.stupro.common.exception.enums.support.NotFoundExceptionEnum;
import baiqitun.stupro.common.exception.support.NotFoundException;
import baiqitun.stupro.common.exception.StuproException;
import baiqitun.stupro.common.service.CaptchaService;
import cn.hutool.captcha.AbstractCaptcha;
import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.ShearCaptcha;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

/**
 * @author kedaji
 */
@Service
public class CaptchaServiceImpl implements CaptchaService {
    private static final long EXPIRED_FLAG = -2;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public AbstractCaptcha save(HttpServletRequest request, int width, int height) {
        ShearCaptcha shearCaptcha = CaptchaUtil.createShearCaptcha(width, height, 6, 4);
        String key = buildKey(request, shearCaptcha.getCode());
        redisTemplate.opsForValue().set(key, shearCaptcha.getCode());
        // 设置图片验证码超时时间5分钟
        redisTemplate.expire(key, 3, TimeUnit.MINUTES);
        return shearCaptcha;
    }

    @Override
    public boolean verify(HttpServletRequest request, String code) {
        String key = buildKey(request, code);
        Boolean hasKey = redisTemplate.hasKey(key);
        if (! hasKey){
            throw new NotFoundException(NotFoundExceptionEnum.CAPTCHA_NOT_FOUND);
        }
        Long expireTime = redisTemplate.getExpire(buildKey(request, code), TimeUnit.MINUTES);
        if (expireTime == null){
            throw new NotFoundException(NotFoundExceptionEnum.CAPTCHA_NOT_FOUND);
        }
        if (expireTime == EXPIRED_FLAG || expireTime == 0){
            // 验证码过期
            throw new StuproException(StuproExceptionEnum.CAPTCHA_EXPIRED);
        }
        String value = (String)redisTemplate.opsForValue().get(key);
        if (code.equals(value)){
            redisTemplate.expire(key, -2, TimeUnit.SECONDS);
            return true;
        }
        return false;
    }

    private String buildKey(HttpServletRequest request, String code){
        return SysConstant.CACHE_PREFIX + "captcha" + SysConstant.CACHE_PREFIX
                + request.getRemoteAddr() +SysConstant.CACHE_PREFIX + code;
    }
}
